<?php

if( ! defined('DOCROOT') )
{
    require_once '/var/www/advancelab/chilik2/unittest/bootstrap.php';
}

class RailsRouterTest extends UnitTestCase
{
    function testingMatchEmpty()
    {
        $request = new Core\MVCRequest;
        $request->uri = '';
        $route = new Implementation\RailsRouter( '', 'testController');
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual( 'testController', $routeInfo->controllerClass );
        $this->assertEqual( array(), $request->variables );
        
        /* $this->dump($route); */
    }
    
    function testingNoMatchEmpty()
    {
        $request = new Core\MVCRequest();
        $request->uri = 'notEmpty';
        
        $route = new Implementation\RailsRouter( '', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual(NULL, $routeInfo);
        /* $this->dump($route); */
    }
    
    function testingMatchEmptyDefaultVars()
    {
        $request = new Core\MVCRequest();
        $request->uri = '';
        
        $route = new Implementation\RailsRouter( '', 'testController', 'action', array('default1' => 'Reality is merely an illusion, albeit a very persistent one.') );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual('action', $routeInfo->action);
        $this->assertEqual(array('default1' => 'Reality is merely an illusion, albeit a very persistent one.'), $request->variables);
        /* $this->dump($route); */
    }
    
    function testingMatchNonEmptyDefaultVars()
    {
        $request = new Core\MVCRequest();
        $request->uri = 'people/einstein';
        
        $route = new Implementation\RailsRouter( 'people/:name', 'testController', 'action', array('framework' => 'chilikframework - cf') );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('framework' => 'chilikframework - cf', 'name' => 'einstein'), $request->variables);
        /* $this->dump($route); 
        $this->dump($request->variables); */
    }
    
    function testingMatchNonEmptyOneVar()
    {
        $request = new Core\MVCRequest();
        $request->uri = 'people/einstein';
        
        $route = new Implementation\RailsRouter( 'people/:name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('name' => 'einstein'), $request->variables);
        
        /* $this->dump($route); */
    }
    
    function testingMatchNonEmptyDefaultVarReused()
    {
        $request = new Core\MVCRequest();
        $request->uri = 'people/einstein';
        
        $route = new Implementation\RailsRouter( 'people/:name', 'testController', array( 'name' => 'chilik' ) );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('name' => 'einstein'), $request->variables);
        
        /* $this->dump($route); */
    }
    
    function testingMatchNonEmptyTwoVar()
    {
        $request = new Core\MVCRequest();
        $request->uri = 'people/newton';
        
        $route = new Implementation\RailsRouter( ':group/:name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('group' => 'people','name' => 'newton'), $request->variables);
        
        /* $this->dump($route); */
    }
    
    function testingMatchComplex()
    {
        $request = new Core\MVCRequest();
        $request->uri = 'people/newton';
        
        $route = new Implementation\RailsRouter( 'people/:slug', 'testController', 'action', array('nr' => '', 'name' => '') );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('nr' => '', 'name' => '','slug' => 'newton'), $request->variables);
        
        $request->uri = 'people/42';
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('nr' => '', 'name' => '','slug' => '42'), $request->variables);
        
        $request->uri = 'people';
        $routeInfo = $route->matches( $request );
        $this->assertEqual(NULL, $routeInfo);
        
        $request->uri = 'people/';
        $routeInfo = $route->matches( $request );
        $this->assertEqual(NULL, $routeInfo);
        /* $this->dump($route); */
    }
    
    function testingPrefix()
    {
        $route = new testRailsRouter( 'entry/:id', 'ignored' );
        $route->prefix('blog/');
        
        $this->assertEqual('blog/entry/:id', $route->getPattern());
        
        /* $this->dump($route); */
    }

    function testingNamedRouter()
    {
        $request = new Core\MVCRequest;
        $request->uri = 'entry/get/89';
        $route = new testNamedRouter( $request );

        $this->assertEqual('entry/get/42', $route->generateUrl( 'get', array('id' => 42) ) );
        $this->assertEqual('entry/42/info', $route->generateUrl( 'info', array('id' => 42) ) );
        $this->assertEqual( 'e/chilik/yes', $route->generateUrl( 'multiple1', array( 'person' => 'chilik', 'relation' => 'yes' ) ) );
        $this->assertEqual( 'chilik/e/yes', $route->generateUrl( 'multiple2', array( 'person' => 'chilik', 'relation' => 'yes' ) ) );
        $this->assertEqual( 'chilik/yes/e', $route->generateUrl( 'multiple3', array( 'person' => 'chilik', 'relation' => 'yes' ) ) );
        
        /* $this->dump($route); */
    }
    
    function testingNamedRouterMissingArgument()
    {
        $request = new Core\MVCRequest;
        $request->uri = 'entry/get/89';
        $route = new testNamedRouter( $request );
        
        try
        {
            $route->generateUrl( 'info', array() );
            $this->fail('Expected exception not thrown.');
        }
        catch( Exception $e )
        {
            $this->assertEqual( "The argument \"id\" was not specified while generating a URL out of the route with pattern \"entry/:id/info\".", $e->getMessage() );
        }
        
        
        /* $this->dump($route); */
    }
    
    function testingMatchWithDifferentUriMatch()
    {
        $request = new Core\MVCRequest;
        $request->host = 'test.host';
        $request->uri = '/people/newton';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( ':site.host/:group/:name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual(':site.host/:group/:name', $routeInfo->matchedRoute);
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('site' => 'test', 'group' => 'people', 'name' => 'newton'), $request->variables);
    }
    
    function testingMatchWithDotInUrl1()
    {
        $request = new Core\MVCRequest;
        $request->host = 'test.host';
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( 'test.host/topic/:list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('test.host/topic/:list/:newsgroup_name', $routeInfo->matchedRoute);
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('list' => 'list', 'newsgroup_name' => 'foo.bar.cf.is.cool'), $request->variables);
    }
    
    function testingMatchWithDotInUrl2()
    {
        $request = new Core\MVCRequest;
        $request->host = 'test.example.com';
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( 'test.:domain.com/topic/:list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('test.:domain.com/topic/:list/:newsgroup_name', $routeInfo->matchedRoute);
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('domain' => 'example','list' => 'list', 'newsgroup_name' => 'foo.bar.cf.is.cool'), $request->variables);
    }
    
    function testingMatchWithDotInUrl3()
    {
        $request = new Core\MVCRequest;
        $request->host = 'test.example.com';
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( 'test.:domain.com/topic/:list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('test.:domain.com/topic/:list/:newsgroup_name', $routeInfo->matchedRoute);
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('domain' => 'example','list' => 'list', 'newsgroup_name' => 'foo.bar.cf.is.cool'), $request->variables);
    }
    
    function testingMatchWithDotInUrl3a()
    {
        $request = new Core\MVCRequest;
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        
        $route = new Implementation\RailsRouter( '/topic/list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual('/topic/list/:newsgroup_name', $routeInfo->matchedRoute);
        $this->assertEqual('testController', $routeInfo->controllerClass);
        $this->assertEqual(array('newsgroup_name' => 'foo.bar.cf.is.cool'), $request->variables);
    }
    
    function testingMatchWithDotInUrl4()
    {
        $request = new Core\MVCRequest;
        $request->host = 'test/host';
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( 'test.host/topic/list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual( NULL, $routeInfo );
    }
    
    function testingMatchWithDotInUrl5()
    {
        $request = new Core\MVCRequest;
        $request->host = 'test.host';
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( 'test/host/topic/list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual( NULL, $routeInfo );
    }
    
    function testingMatchWithDotInUrl6()
    {
        $request = new Core\MVCRequest;
        $request->host = 'hostname';
        $request->uri = '/topic/list/foo.bar.cf.is.cool';
        $request->requestId = $request->host.$request->uri;
        
        $route = new testRailsRouterForFullUri( '/topic/list/:newsgroup_name', 'testController' );
        $routeInfo = $route->matches( $request );
        
        $this->assertEqual( NULL, $routeInfo );
    }
    
}
